//
//  BlocksAndClosuresTest.h
//  test_simple_project
//
//  块(Block)和闭包语法特性测试文件
//  测试各种Block语法形式和使用场景
//

#import <Foundation/Foundation.h>

#pragma mark - Block类型定义

// 基础Block类型定义
typedef void (^BasicBlock)(void);
typedef void (^ParameterBlock)(NSString *parameter);
typedef NSString * (^ReturnBlock)(NSString *input);
typedef BOOL (^PredicateBlock)(id object);
typedef NSComparisonResult (^ComparatorBlock)(id obj1, id obj2);

// 复杂Block类型定义
typedef void (^CompletionBlock)(BOOL success, NSError * _Nullable error);
typedef void (^ProgressBlock)(float progress, NSString *status);
typedef id _Nullable (^TransformBlock)(id input);
typedef void (^AsyncBlock)(void (^callback)(id result));

// 嵌套Block类型定义
typedef void (^NestedBlock)(void (^innerBlock)(NSString *result));
typedef NSString * (^BlockReturningBlock)(void);
typedef void (^BlockWithBlockParameter)(BasicBlock block);

// 数组和字典操作Block类型
typedef void (^ArrayEnumerationBlock)(id object, NSUInteger index, BOOL *stop);
typedef void (^DictionaryEnumerationBlock)(id key, id value, BOOL *stop);
typedef id (^MapBlock)(id object);
typedef id (^ReduceBlock)(id accumulator, id object);

#pragma mark - 主测试类

@interface BlocksAndClosuresTest : NSObject

#pragma mark - Block属性

// Block作为属性
@property (copy, nonatomic) BasicBlock basicBlockProperty;
@property (copy, nonatomic) ParameterBlock parameterBlockProperty;
@property (copy, nonatomic) ReturnBlock returnBlockProperty;
@property (copy, nonatomic) CompletionBlock completionBlockProperty;

// 可选Block属性
@property (copy, nonatomic, nullable) PredicateBlock optionalPredicateBlock;
@property (copy, nonatomic, nullable) TransformBlock optionalTransformBlock;

#pragma mark - Block作为参数的方法

// 基础Block参数方法
- (void)executeBasicBlock:(BasicBlock)block;
- (void)executeParameterBlock:(ParameterBlock)block withParameter:(NSString *)parameter;
- (NSString *)executeReturnBlock:(ReturnBlock)block withInput:(NSString *)input;

// 异步操作Block方法
- (void)performAsyncOperationWithCompletion:(CompletionBlock)completion;
- (void)performLongRunningTaskWithProgress:(ProgressBlock)progress 
                                completion:(CompletionBlock)completion;

// 数据处理Block方法
- (NSArray *)filterArray:(NSArray *)array withPredicate:(PredicateBlock)predicate;
- (NSArray *)mapArray:(NSArray *)array withTransform:(TransformBlock)transform;
- (id)reduceArray:(NSArray *)array withInitialValue:(id)initialValue reducer:(ReduceBlock)reducer;

// 排序Block方法
- (NSArray *)sortArray:(NSArray *)array withComparator:(ComparatorBlock)comparator;
- (NSArray *)sortedArrayUsingBlock:(NSArray *)array;

#pragma mark - Block作为返回值的方法

// 返回Block的方法
- (BasicBlock)createBasicBlock;
- (ParameterBlock)createParameterBlockWithPrefix:(NSString *)prefix;
- (ReturnBlock)createReturnBlockWithSuffix:(NSString *)suffix;
- (PredicateBlock)createPredicateBlockForClass:(Class)targetClass;

// 创建复杂Block的方法
- (CompletionBlock)createCompletionBlockWithSuccessMessage:(NSString *)successMessage;
- (TransformBlock)createTransformBlockWithOperation:(NSString *)operation;

#pragma mark - 嵌套Block方法

// 嵌套Block使用
- (void)executeNestedBlock:(NestedBlock)nestedBlock;
- (void)chainBlocks:(BasicBlock)firstBlock second:(BasicBlock)secondBlock;
- (void)executeBlockSequence:(NSArray<BasicBlock> *)blocks;

#pragma mark - Block变量修饰符测试

// __block变量测试
- (void)demonstrateBlockVariableModifiers;
- (NSInteger)countWithBlockVariable:(NSArray *)array;
- (void)modifyExternalVariableWithBlock;

#pragma mark - 高级Block用法

// Block作为回调
- (void)registerCallback:(BasicBlock)callback;
- (void)triggerRegisteredCallbacks;

// Block用于事件处理
- (void)addEventListener:(NSString *)eventName handler:(ParameterBlock)handler;
- (void)removeEventListener:(NSString *)eventName;
- (void)triggerEvent:(NSString *)eventName withData:(NSString *)data;

// Block用于函数式编程
- (NSArray *)functionalProgrammingDemo:(NSArray *)numbers;
- (NSDictionary *)groupArray:(NSArray *)array byKey:(NSString *(^)(id object))keyExtractor;

#pragma mark - Block内存管理

// Block内存管理测试
- (void)demonstrateBlockMemoryManagement;
- (void)demonstrateWeakSelfPattern;
- (void)demonstrateStrongWeakDance;

#pragma mark - 全局Block函数声明

// 全局Block变量
extern BasicBlock GlobalBasicBlock;
extern ParameterBlock GlobalParameterBlock;
extern ReturnBlock GlobalReturnBlock;

// 全局函数返回Block
BasicBlock CreateGlobalBasicBlock(void);
ParameterBlock CreateGlobalParameterBlock(NSString *prefix);
ReturnBlock CreateGlobalReturnBlock(NSString *suffix);

// 全局函数接受Block参数
void ExecuteGlobalBlock(BasicBlock block);
NSArray *FilterGlobalArray(NSArray *array, PredicateBlock predicate);
void PerformGlobalAsyncOperation(CompletionBlock completion);

@end

#pragma mark - Block工具类

/**
 * Block工具类，提供常用的Block操作
 */
@interface BlockUtilities : NSObject

// 常用Block创建
+ (PredicateBlock)isKindOfClassBlock:(Class)targetClass;
+ (PredicateBlock)isEqualToObjectBlock:(id)targetObject;
+ (TransformBlock)stringTransformBlock:(NSString *)operation;
+ (ComparatorBlock)stringComparatorBlock;

// Block组合操作
+ (PredicateBlock)andPredicateBlock:(PredicateBlock)first second:(PredicateBlock)second;
+ (PredicateBlock)orPredicateBlock:(PredicateBlock)first second:(PredicateBlock)second;
+ (PredicateBlock)notPredicateBlock:(PredicateBlock)predicate;

// Block缓存和复用
+ (void)cacheBlock:(id)block forKey:(NSString *)key;
+ (id)cachedBlockForKey:(NSString *)key;
+ (void)clearBlockCache;

@end

#pragma mark - Block常量和宏定义

// Block相关常量
extern NSString * const BlockTestNotificationName;
extern NSString * const BlockTestErrorDomain;

// Block相关宏定义
#define WEAK_SELF __weak typeof(self) weakSelf = self
#define STRONG_SELF __strong typeof(weakSelf) strongSelf = weakSelf

// Block执行宏
#define EXECUTE_BLOCK_SAFELY(block, ...) \
    do { \
        if (block) { \
            block(__VA_ARGS__); \
        } \
    } while(0)

#define EXECUTE_BLOCK_ON_MAIN_QUEUE(block, ...) \
    do { \
        if (block) { \
            dispatch_async(dispatch_get_main_queue(), ^{ \
                block(__VA_ARGS__); \
            }); \
        } \
    } while(0)
